#include <linux/module.h>
#include <linux/string.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>

#define DRIVER_NAME     ("hkm-device-tree")

static int hkm_devtree_probe(struct platform_device *pdev)
{
    struct device_node *node = pdev->dev.of_node;
    u32 i = 0;
    s32 ret = 0;
    u32 value = 0;
    u32 arr[4] = {0};
    const char *name = NULL;

    printk(KERN_DEBUG "call hkm device tree driver probe function\n");

    if(NULL != node)
    {
        ret = of_property_read_string(node, "hkm,name", &name);
        if(0 == ret)
        {
            printk(KERN_DEBUG "hkm name is '%s' in device tree\n", name);
        }

        ret = of_property_read_u32(node, "uint-value", &value);
        if(0 == ret)
        {
            printk(KERN_DEBUG "value is %u in device tree\n", value);
        }

        ret = of_property_read_bool(node, "dev-enable");
        if(true == ret)
        {
            printk(KERN_DEBUG "device is enable\n");
        }
 
        ret = of_property_read_u32_array(node, "uint-array", arr, 4);
        if(0 == ret)
        {
            printk(KERN_DEBUG "value array, 0x%x, 0x%x, 0x%x, 0x%x\n", arr[0], arr[1], arr[2], arr[3]);
        }
        
        ret = of_property_read_u32_index(node, "uint-array", 3, &value);
        if(0 == ret)
        {
            printk(KERN_DEBUG "index 3 item of array:0x%x\n", value);
        }

        memset(arr, 0, sizeof(arr));

        ret = of_property_read_variable_u32_array(node, "uint-array", arr, 2, 0);
        if(2 == ret)
        {
            printk(KERN_DEBUG "read 2 item of array:0x%x, 0x%x\n", arr[0], arr[1]);
        }
   }


    return 0;
}

static int hkm_devtree_remove(struct platform_device *pdev)
{
    printk(KERN_DEBUG "call hkm device tree driver remove function\n");

    return 0;
}

#ifdef CONFIG_OF
static struct of_device_id hkm_devtree_of_match_table[] = {
    {.compatible = "sdc,hkm"},
    {/*end of list*/},
};

MODULE_DEVICE_TABLE(of, hkm_devtree_of_match_table);
#else
#define hkm_devtree_of_match_table  
#endif


static struct platform_driver hkm_devtree_driver = {
    .driver = {
        .name = DRIVER_NAME,
        .owner = THIS_MODULE,
        .of_match_table = hkm_devtree_of_match_table,
    },

    .probe = hkm_devtree_probe,
    .remove = hkm_devtree_remove,
};

static int __init hkm_init(void)
{
    printk(KERN_DEBUG "hello, sdc\n");

    return platform_driver_register(&hkm_devtree_driver);
}

static void __exit hkm_exit(void)
{
    printk(KERN_DEBUG "bye, sdc\n");

}

module_init(hkm_init);
module_exit(hkm_exit);

MODULE_DESCRIPTION("KM in kernel source");
MODULE_AUTHOR("sdc");
MODULE_LICENSE("GPL");
